﻿/*!	@file	r_draw_core.h
	@brief	描画システム
Copyright (c) 2010 Yuya Yamaguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef _R_DRAW_CORE_H_
#define _R_DRAW_CORE_H_

#include "../rtti/r_rtti_class_base.h"
#include "../util/r_util_singleton.h"
#include "../alloc/r_alloc_new_delete.h"
#include "r_draw_def.h"

namespace r{
	namespace draw{
class SwapChain;
struct Texture2DDesc;
class Texture2D;
class Texture3D;
class RenderTarget;
class DepthStencil;
struct SamplerDesc;
class Sampler;
struct RasterizerDesc;
class RasterizerState;
struct BlendStateDesc;
class BlendState;
struct DepthStencilStateDesc;
class DepthStencilState;


class InputLayoutDesc;
class InputLayout;
class VertexBuffer;
class IndexBuffer;
class ConstantBuffer;

class VertexShader;
class PixelShader;
class GeometryShader;

class Context;
	}
}

namespace r{
	namespace draw{

		//! 描画コアクラス
		/*! 描画処理の基本クラス
		スレッドセーフでは無いので必ずメインスレッドから呼び出しを行ってください。
		*/
		class Core : public r::rtti::ClassBase
		{
			RRTTI_REFLECTION_DECLARE
			RSINGLETONTGET_DECLARE ( Core )
			RALLOC_PLACEMENT_NEW_DELETE_DECLEARE
		protected:
			//! コンストラクタ
			Core() {}
			//! デストラクタ
			virtual ~Core() {}
		public:
			//! スワップチェインの取得
			virtual	const SwapChain*		getSwapChain() const {
				return NULL;
			}
		protected:
			//! 2Dテクスチャの作成
			/*!
			@param	desc	[in]	テクスチャ定義データ
			@retval	作成されたテクスチャデータ
			*/
			virtual	Texture2D*			createTexture2D ( const Texture2DDesc& desc ) {
				return NULL;
			}
			//! メモリ内のファイルデータをもとに2Dテクスチャを作成する
			/*!
			@param	desc		[in]	テクスチャ定義データ※利用するのはusageとbindflagのみ
			@param	buff		[in]	バッファデータ
			@param	buffSize	[in]	バッファサイズ
			@reval	作成されたテクスチャデータ
			*/
			virtual	Texture2D*			createTexture2D ( const Texture2DDesc& desc, const void* buff, r_size buffSize ) {
				return NULL;
			}
			//! レンダーターゲットを作成する
			/*!
			@param	width	[in]	レンダーターゲットの横幅
			@param	height	[in]	レンダーターゲットの縦幅
			@param	format	[in]	レンダーターゲットのフォーマット
			@param	name	[in]	レンダーターゲットの名前
			@retval	レンダーターゲットクラスへのポインタ
			*/
			virtual RenderTarget*			createRenderTarget ( r_ui32 width, r_ui32 height, ImageFormat format, const r_cstr name ) {
				return NULL;
			}
			//! 深度ステンシルビューを作成する
			/*!
			@param	width	[in]	深度ステンシルビューの横幅
			@param	height	[in]	深度ステンシルビューの縦幅
			@param	format	[in]	深度ステンシルビューのフォーマット
			@param	name	[in]	深度ステンシルビューの名前
			@retval	深度ステンシルビュークラスへのポインタ
			*/
			virtual DepthStencil*			createDepthStencil ( r_ui32 width, r_ui32 height, ImageFormat format, const r_cstr name ) {
				return NULL;
			}
			//! サンプラステートを作成する
			/*!
			*/
			virtual	Sampler*				createSamplerState ( const SamplerDesc& desc ) {
				return NULL;
			}
			//! ラスタステートを作成する
			/*!
			*/
			virtual	RasterizerState*		createRasterizerState ( const RasterizerDesc& desc ) {
				return NULL;
			}
			//! ブレンドステートを作成する
			/*!
			*/
			virtual	BlendState*			createBlendState ( const BlendStateDesc& desc ) {
				return NULL;
			}
			//! 深度ステンシルステートを作成する
			/*!
			*/
			virtual	DepthStencilState*	createDepthStencilState ( const DepthStencilStateDesc& desc ) {
				return NULL;
			}

			//! 頂点レイアウトの作成
			/*!
			*/
			virtual	InputLayout*			createInputLayout ( const InputLayoutDesc& layoutdesc, const VertexShader* shader ) {
				return NULL;
			}
			//! 頂点バッファの作成
			/*!
			@param	stride		[in]	1頂点サイズ
			@param	numVertex	[in]	頂点数
			*/
			virtual VertexBuffer*			createVertexBuffer ( r_ui32 stride, r_ui32 numVertex ) {
				return NULL;
			}
			//! インデックスバッファの作成
			/*!
			@param	numIndex	[in]	インデックス数
			*/
			virtual IndexBuffer*			createIndexBuffer ( r_ui32 numIndex ) {
				return NULL;
			}
			//! コンスタントバッファの作成
			/*!
			@param	size	[in]	定数構造体サイズ
			*/
			virtual ConstantBuffer*		createConstantBuffer ( r_ui32 size ) {
				return NULL;
			}

			//! 頂点シェーダの作成
			/*!
			@param	buffer			[in]	シェーダコード
			@param	buffSize		[in]	シェーダコードサイズ
			@param	entryFuncName	[in]	エントリー関数名
			@param	fileName		[in]	ファイル名
			*/
			virtual	VertexShader*			createVertexShader ( void* buffer, r_size buffSize, const r_cstr entryFuncName, const r_cstr fileName ) {
				return NULL;
			}
			//! ピクセルシェーダの作成
			/*!
			@param	buffer			[in]	シェーダコード
			@param	buffSize		[in]	シェーダコードサイズ
			@param	entryFuncName	[in]	エントリー関数名
			@param	fileName		[in]	ファイル名
			*/
			virtual	PixelShader*			createPixelShader ( void* buffer, r_size buffSize, const r_cstr entryFuncName, const r_cstr fileName ) {
				return NULL;
			}
		//class GeometryShader;
		protected:
			//! テクスチャの破棄
			/*!
			*/
			virtual void						destroyTexture2D ( Texture2D* texture ) {}
			//! レンダーターゲットの破棄
			/*!
			*/
			virtual void						destroyRenderTarget ( RenderTarget* target ) {}
			//! 深度ステンシルビューの破棄
			/*!
			*/
			virtual void						destroyDepthStencil ( DepthStencil* target ) {}
			//! サンプラステートの破棄
			/*!
			*/
			virtual	void						destroySamplerState ( Sampler* sampler ) {}
			//! ラスタステートの破棄
			/*!
			*/
			virtual	void						destroyRasterizerState ( RasterizerState* raster ) {}
			//! ブレンドステートの破棄
			/*!
			*/
			virtual	void						destroyBlendState ( BlendState* blend ) {}
			//! 深度ステンシルステートの破棄
			/*!
			*/
			virtual	void						destroyDepthStencilState ( DepthStencilState* depth ) {}

			//! 頂点レイアウトの破棄
			/*!
			*/
			virtual void						destroyInputLayout ( InputLayout* layout ) {}
			//! 頂点バッファの破棄
			/*!
			*/
			virtual void						destroyVertexBuffer ( VertexBuffer* buffer ) {}
			//! インデックスバッファの破棄
			/*!
			*/
			virtual void						destroyIndexBuffer ( IndexBuffer* buffer ) {}
			//! コンスタントバッファの破棄
			/*!
			*/
			virtual	void						destroyConstantBuffer ( ConstantBuffer* buffer ) {}

			//! 頂点シェーダの破棄
			/*!
			*/
			virtual void						destroyVertexShader ( VertexShader* shader ) {}
			//! フラグメントシェーダの破棄
			/*!
			*/
			virtual void						destroyPixelShader ( PixelShader* shader ) {}
		public:
			// システム保有データへのアクセス
			//! 最終出力用のレンダーターゲットを取得する
			/*!
			*/
			virtual	RenderTarget*			getRenderTargetCore() const {
				return NULL;
			}
			//! 標準の深度ステンシルを取得する
			/*!
			*/
			virtual	DepthStencil*			getDepthStencilCore() const {
				return NULL;
			}
			//! コンテキストを取得する
			/*! この関数はライブラリの提供する実行スレッド毎に異なる実体を返します。
			*/
			virtual Context*				getContext() const {
				return NULL;
			}
		public:
			// システム用
			//! 描画コマンドのマージ
			/*! 全スレッドにおいて1フレーム内の全ての描画コマンドの発行を終えてから実行してください。
			*/
			virtual	void						mirgeCommand() {}
			//! 描画コマンドの実行
			/*! マージ済みのコマンドを実行します。
			*/
			virtual	void						executeCommand() {}
		public:
			//! システムエラーの検知
			virtual r_si32						checkErr() const {
				return 0;
			}
		protected:
		private:
			// 破棄関数アクセスの為
			friend class Texture2D;
			friend class Texture3D;
			friend class RenderTarget;
			friend class DepthStencil;
			friend class Sampler;
			friend class RasterizerState;
			friend class BlendState;
			friend class DepthStencilState;

			friend class InputLayout;
			friend class VertexBuffer;
			friend class IndexBuffer;
			friend class ConstantBuffer;

			friend class VertexShader;
			friend class PixelShader;
			friend class GeometryShader;
		};
	}
}

#endif // _R_DRAW_CORE_H_
